﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using Ue.Components.FileWatcher;

namespace Ue.Infrastructure.Configuration
{
    public class ConfigurationSource : IConfigurationSource
    {
        private Lazy<System.Configuration.Configuration> lazyConfiguration;
        private readonly string sectionName;

        public ConfigurationSource(string configFilePath,string sectionName,IFileMonitorManager fileMonitorManager)
        {
            this.sectionName = sectionName;
            this.lazyConfiguration = this.CreateLazyConfiguration(configFilePath);

            fileMonitorManager.TryAcquireMonitor(
                configFilePath,
                fileMonitor => this.lazyConfiguration = this.CreateLazyConfiguration(configFilePath));
        }

        #region IConfigurationSource 成员

        public System.Configuration.Configuration Configuration
        {
            get { return this.lazyConfiguration.Value; }
        }

        public ConfigurationSection Section
        {
            get { return this.GetSection(this.sectionName); }
        }

        public ConfigurationSection GetSection(string sectionName)
        {
            try
            {
                return this.lazyConfiguration.Value.GetSection(sectionName);
            }
            catch
            {
                return null;
            }
        }

        #endregion

        private System.Configuration.Configuration Loading(string path)
        {
            if (!File.Exists(path))
            {
                return null;
            }

            try
            {
                return ConfigurationManager.OpenMappedMachineConfiguration(new ConfigurationFileMap(path));
            }
            catch (ConfigurationErrorsException)
            {
                return null;
            }
        }

        private Lazy<System.Configuration.Configuration> CreateLazyConfiguration(string path)
        {
            return new Lazy<System.Configuration.Configuration>(() => this.Loading(path));
        }
    }
}
